-------------------------------------------------------------------------------
--     Pengo decode table
--		/*  opcode (M1=0)            data (M1=1)                   address     */
--		/*  0    1    2    3         0    1    2    3          A12  A8  A4  A0 */
--		{ 0xa0,0x80,0xa8,0x88 }, { 0x28,0xa8,0x08,0x88 },	/* ...0...0...0...0 */
--		{ 0x28,0xa8,0x08,0x88 }, { 0xa0,0x80,0xa8,0x88 },	/* ...0...0...0...1 */
--		{ 0xa0,0x80,0x20,0x00 }, { 0xa0,0x80,0x20,0x00 },	/* ...0...0...1...0 */
--		{ 0x08,0x28,0x88,0xa8 }, { 0xa0,0x80,0xa8,0x88 },	/* ...0...0...1...1 */
--		{ 0x08,0x00,0x88,0x80 }, { 0x28,0xa8,0x08,0x88 },	/* ...0...1...0...0 */
--		{ 0xa0,0x80,0x20,0x00 }, { 0x08,0x00,0x88,0x80 },	/* ...0...1...0...1 */
--		{ 0xa0,0x80,0x20,0x00 }, { 0xa0,0x80,0x20,0x00 },	/* ...0...1...1...0 */
--		{ 0xa0,0x80,0x20,0x00 }, { 0x00,0x08,0x20,0x28 },	/* ...0...1...1...1 */
--		{ 0x88,0x80,0x08,0x00 }, { 0xa0,0x80,0x20,0x00 },	/* ...1...0...0...0 */
--		{ 0x88,0x80,0x08,0x00 }, { 0x00,0x08,0x20,0x28 },	/* ...1...0...0...1 */
--		{ 0x08,0x28,0x88,0xa8 }, { 0x08,0x28,0x88,0xa8 },	/* ...1...0...1...0 */
--		{ 0xa0,0x80,0xa8,0x88 }, { 0xa0,0x80,0x20,0x00 },	/* ...1...0...1...1 */
--		{ 0x08,0x00,0x88,0x80 }, { 0x88,0x80,0x08,0x00 },	/* ...1...1...0...0 */
--		{ 0x00,0x08,0x20,0x28 }, { 0x88,0x80,0x08,0x00 },	/* ...1...1...0...1 */
--		{ 0x08,0x28,0x88,0xa8 }, { 0x08,0x28,0x88,0xa8 },	/* ...1...1...1...0 */
--		{ 0x08,0x00,0x88,0x80 }, { 0xa0,0x80,0x20,0x00 }	/* ...1...1...1...1 */
-------------------------------------------------------------------------------

library ieee;
	use ieee.std_logic_1164.all;
	use ieee.numeric_std.all;

entity sega_decode is
	port (
		I_DEC    : in  std_logic;
		I_CK     : in  std_logic;
		--
		I_A      : in  std_logic_vector(6 downto 0);
		I_D      : in  std_logic_vector(7 downto 0);
		O_D      : out std_logic_vector(7 downto 0)
	);

end sega_decode;

architecture rtl of sega_decode is
	signal sel     : std_logic_vector(6 downto 0);
	signal val     : std_logic_vector(2 downto 0);
begin
	p_decoder : process
	begin
		wait until rising_edge(I_CK);
		if (I_DEC = '0') then
			O_D <= I_D; -- passthough
		else
			sel <= I_A xor ("00000" & I_D(7) & I_D(7));
			O_D(7) <= I_D(7) xor val(2);
			O_D(6) <= I_D(6);
			O_D(5) <= I_D(7) xor val(1);
			O_D(4) <= I_D(4);
			O_D(3) <= I_D(7) xor val(0);
			O_D(2) <= I_D(2);
			O_D(1) <= I_D(1);
			O_D(0) <= I_D(0);
			case sel is -- M1 A12 A8 A4 A0 D5 D3
				when "0000000" => val <= "110";
				when "0000001" => val <= "100";
				when "0000010" => val <= "111";
				when "0000011" => val <= "101";
				when "0000100" => val <= "011";
				when "0000101" => val <= "111";
				when "0000110" => val <= "001";
				when "0000111" => val <= "101";
				when "0001000" => val <= "110";
				when "0001001" => val <= "100";
				when "0001010" => val <= "010";
				when "0001011" => val <= "000";
				when "0001100" => val <= "001";
				when "0001101" => val <= "011";
				when "0001110" => val <= "101";
				when "0001111" => val <= "111";
				when "0010000" => val <= "001";
				when "0010001" => val <= "000";
				when "0010010" => val <= "101";
				when "0010011" => val <= "100";
				when "0010100" => val <= "110";
				when "0010101" => val <= "100";
				when "0010110" => val <= "010";
				when "0010111" => val <= "000";
				when "0011000" => val <= "110";
				when "0011001" => val <= "100";
				when "0011010" => val <= "010";
				when "0011011" => val <= "000";
				when "0011100" => val <= "110";
				when "0011101" => val <= "100";
				when "0011110" => val <= "010";
				when "0011111" => val <= "000";
				when "0100000" => val <= "101";
				when "0100001" => val <= "100";
				when "0100010" => val <= "001";
				when "0100011" => val <= "000";
				when "0100100" => val <= "101";
				when "0100101" => val <= "100";
				when "0100110" => val <= "001";
				when "0100111" => val <= "000";
				when "0101000" => val <= "001";
				when "0101001" => val <= "011";
				when "0101010" => val <= "101";
				when "0101011" => val <= "111";
				when "0101100" => val <= "110";
				when "0101101" => val <= "100";
				when "0101110" => val <= "111";
				when "0101111" => val <= "101";
				when "0110000" => val <= "001";
				when "0110001" => val <= "000";
				when "0110010" => val <= "101";
				when "0110011" => val <= "100";
				when "0110100" => val <= "000";
				when "0110101" => val <= "001";
				when "0110110" => val <= "010";
				when "0110111" => val <= "011";
				when "0111000" => val <= "001";
				when "0111001" => val <= "011";
				when "0111010" => val <= "101";
				when "0111011" => val <= "111";
				when "0111100" => val <= "001";
				when "0111101" => val <= "000";
				when "0111110" => val <= "101";
				when "0111111" => val <= "100";
				when "1000000" => val <= "011";
				when "1000001" => val <= "111";
				when "1000010" => val <= "001";
				when "1000011" => val <= "101";
				when "1000100" => val <= "110";
				when "1000101" => val <= "100";
				when "1000110" => val <= "111";
				when "1000111" => val <= "101";
				when "1001000" => val <= "110";
				when "1001001" => val <= "100";
				when "1001010" => val <= "010";
				when "1001011" => val <= "000";
				when "1001100" => val <= "110";
				when "1001101" => val <= "100";
				when "1001110" => val <= "111";
				when "1001111" => val <= "101";
				when "1010000" => val <= "011";
				when "1010001" => val <= "111";
				when "1010010" => val <= "001";
				when "1010011" => val <= "101";
				when "1010100" => val <= "001";
				when "1010101" => val <= "000";
				when "1010110" => val <= "101";
				when "1010111" => val <= "100";
				when "1011000" => val <= "110";
				when "1011001" => val <= "100";
				when "1011010" => val <= "010";
				when "1011011" => val <= "000";
				when "1011100" => val <= "000";
				when "1011101" => val <= "001";
				when "1011110" => val <= "010";
				when "1011111" => val <= "011";
				when "1100000" => val <= "110";
				when "1100001" => val <= "100";
				when "1100010" => val <= "010";
				when "1100011" => val <= "000";
				when "1100100" => val <= "000";
				when "1100101" => val <= "001";
				when "1100110" => val <= "010";
				when "1100111" => val <= "011";
				when "1101000" => val <= "001";
				when "1101001" => val <= "011";
				when "1101010" => val <= "101";
				when "1101011" => val <= "111";
				when "1101100" => val <= "110";
				when "1101101" => val <= "100";
				when "1101110" => val <= "010";
				when "1101111" => val <= "000";
				when "1110000" => val <= "101";
				when "1110001" => val <= "100";
				when "1110010" => val <= "001";
				when "1110011" => val <= "000";
				when "1110100" => val <= "101";
				when "1110101" => val <= "100";
				when "1110110" => val <= "001";
				when "1110111" => val <= "000";
				when "1111000" => val <= "001";
				when "1111001" => val <= "011";
				when "1111010" => val <= "101";
				when "1111011" => val <= "111";
				when "1111100" => val <= "110";
				when "1111101" => val <= "100";
				when "1111110" => val <= "010";
				when "1111111" => val <= "000";
				when others => null;
			end case;
		end if;
	end process;
end rtl;
